package io.chance.receiverlei.main;

import io.chance.receiverlei.channel.ChannelCloseHandle;
import io.chance.receiverlei.channel.ChannelOpenHandle;
import io.chance.receiverlei.channel.MessageDecode;
import io.chance.receiverlei.channel.MsgReceiverHandler;
import io.chance.receiverlei.channel.MsgStoreHandler;
import io.chance.receiverlei.db.DbManager;
import lrq.common.MyLog;
import lrq.common.PropertiesUnit;
import org.apache.log4j.Logger;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

public class AppStart {

    public static final String logName = "dataRecevier";
    public static final String connectLogName = "connect";

    private static Logger log = null;

    public static void main(String[] args) {
        if (args.length > 0) {
            PropertiesUnit.setPropertiesBasePath(args[0]);
        }
        MyLog.setRootPath(PropertiesUnit.getValue("logPath"));
        MyLog.setOutToConsole(PropertiesUnit.getBoolean("outToConsole"));
        log = MyLog.getLogger(AppStart.logName);
        int port = PropertiesUnit.getInt("port");
        log.info("监听端口：" + port);

        //启动spring容器
        try {
            initSpring();
        }
        catch (Exception e) {
            log.error("初始化spring容器出错", e);
        }
//        DbManager.Init();//初始化数据库访问
        //RedisDbExecute.resetDB();
        //StationService.getInstance().setAllStationOffline();//把所有点的状态重置为下线
        startNetty(port);
    }

    /**
     * 初始化spring容器，启动quartz定时器
     * gislin
     * 2016年2月23日
     *
     * @throws UnsupportedEncodingException
     */
    private static void initSpring() throws UnsupportedEncodingException {
        // 加载spring容器，启动定时器
        String jarPath = PropertiesUnit.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        jarPath = java.net.URLDecoder.decode(jarPath, "UTF-8");//转换处理中文及空格
        jarPath = new File(jarPath).getParent();
        File configFile = new File(jarPath + "/config/spring-config.xml");
        if (configFile.exists()) {
            new FileSystemXmlApplicationContext(configFile.getPath());
            log.info("从" + configFile.getPath() + "加载spring");
        }
        else {
//            new ClassPathXmlApplicationContext("./config/spring-config.xml");
            new FileSystemXmlApplicationContext("config/spring-config.xml");
            log.info("从classPath加载spring");
        }
    }

    /**
     * 启动netty，接收报文
     * gislin
     * 2016年2月16日
     */
    private static void startNetty(int port) {
        NioServerSocketChannelFactory channelFactory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
        ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);

        ChannelPipelineFactory channelPipelineFactory = new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline channelPipeline = Channels.pipeline();
                channelPipeline.addFirst("openHandle", new ChannelOpenHandle());
                channelPipeline.addFirst("MessageDecode", new MessageDecode());
                channelPipeline.addLast("closeHandle", new ChannelCloseHandle());
                channelPipeline.addLast("handle", new MsgReceiverHandler());
//                channelPipeline.addLast("handle", new MsgStoreHandler());
                return channelPipeline;
            }
        };

        bootstrap.setOption("child.reuseAddress", true);
        bootstrap.setPipelineFactory(channelPipelineFactory);
        bootstrap.bind(new InetSocketAddress(port));
    }
}
